package com.test.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.test.model.AccessToken;
import com.test.util.ResultUtils;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/***
 * 微信授权获取用户openid以及用户基本信息
 * @author xiaozhong
 * 接口编写参考地址：
 * https://blog.csdn.net/qq_34322008/article/details/90053997
 * 
 * 1.微信测试账号申请
 * https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
 * 2.使用自己的微信扫码关注测试微信公众号
 * 
 * 3.在测试账号中配置网页账号-网页授权获取用户基本信息接口权限
 * 点击右侧修改按钮，填写授权回调页面域名
 * 
 * 注意：项目启动以后需要在微信开发者工具中打开。
 * 微信开发者工具，使用关注了微信公众号的微信登陆
 * 
 */
@RestController
@RequestMapping("/weixin")
public class WeixinController {

	private static Logger logger = LoggerFactory.getLogger(WeixinController.class);
	
	private static String wx_appid ="wx8249cffa42281f99";//微信公众测试账号appid
	
	private static String wx_appsecret ="9421ae45f0fdcae5e66244f7c93d4cc0";//微信公众测试账号appsecret
	
	private String renzheng="false";//是否授权了 true认证了  false未认证
	private String userToken="";//记录用户token
	
	@GetMapping("/auth")
	public void auth(@RequestParam("code") String code) {
		System.out.println("--------------------登陆认证对比开始----------------------");
		logger.info("开始执行auth方法…");
		//第一步用户同意授权，获取code
		logger.info("第一步获取code值：");
		logger.info("code ="+ code);
		//第二步通过code换取网页授权access_token
		logger.info("第二步通过code换取网页授权access_token值：");
		String accesstokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
		accesstokenUrl += "?appid="+wx_appid;
		accesstokenUrl += "&secret="+wx_appsecret;
		accesstokenUrl += "&code=" + code;
		accesstokenUrl += "&grant_type=authorization_code";
		RestTemplate restTemplate = new RestTemplate();
		//返回结果
		String accesstokenResponse = restTemplate.getForObject(accesstokenUrl, String.class);
		logger.info("accesstokenResponse ="+ accesstokenResponse);
		//
		/***解析accesstokenResponse转换成实体类
		 * {
			"access_token":"40_B3wmbjM1Q1Hbw4IgQ2sE_pBlPPNMbm9lBivP-GkaHoD1zgQVA7KCE1wTL8l_5SkdVU1zL-gRD3UYhmaTJ-yXrw",
			"expires_in":7200,
			"refresh_token":"40_h8GSRPjO90z1K2yZu0pjSnk_PHX4PUwNY_F67hAiWn6TqyfVntv1-XawvsGuExwXruYUG1pZPkfzbdwbHYQWaw",
			"openid":"op4jLs9hygkoKEy_P_GY1ipJxQ04",
			"scope":"snsapi_userinfo"
		   }
		 */
		AccessToken accessToken = JSON.parseObject(accesstokenResponse, AccessToken.class);
		
		//第三步刷新access_token（如果需要）
		logger.info("第三步刷新access_token（如果需要）：");
		String refreshUrl ="https://api.weixin.qq.com/sns/oauth2/refresh_token";
		refreshUrl +="?appid="+wx_appid;
		refreshUrl +="&grant_type=refresh_token";
		refreshUrl +="&refresh_token="+accessToken.getRefresh_token();//获取第二步的refresh_token后，请求以下链接获取access_token： c
		String refreshResponse = restTemplate.getForObject(refreshUrl, String.class);
		logger.info("refreshResponse ="+ refreshResponse);
		
		//第四步拉取用户信息(需scope为 snsapi_userinfo)
		logger.info("第四步拉取用户信息(需scope为 snsapi_userinfo)：");
		String userUrl="https://api.weixin.qq.com/sns/userinfo";
		userUrl +="?access_token="+accessToken.getAccess_token();//获取第二步中access_token
		userUrl +="&openid="+accessToken.getOpenid();//获取第二步中的openid
		userUrl +="&lang=zh_CN";
		String userResponse = restTemplate.getForObject(userUrl, String.class);
		logger.info("userResponse ="+ userResponse);
		//解析数据出来，返回字段注解：https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#2
		//第四步那里
		
		//模拟登陆将这里将状态改为认证了
		renzheng="ture";
		System.out.println("--------------------登陆认证对比结束----------------------");
		
	}
	
	/****
	 * 微信授权认证回调校验方法
	 * @param bizToken
	 * @param phone
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/checkAuthState", method =RequestMethod.POST)
	public ResultUtils checkAuthState(@RequestParam("token")String token) {
		System.out.println("--------------------执行回调开始----------------------");
		System.out.println("token："+token);
		ResultUtils result=new ResultUtils();
		
		//判断用户token
		if(token.equals(userToken)) {
			//判断是否登陆成功
			if("ture".equals(renzheng)) {
				result.setCode(ResultUtils.CODE_SUCCESS);
				result.setMsg("登陆成功");
				System.out.println("登陆成功");
				
			}else {
				result.setCode(ResultUtils.CODE_ERROR);
				result.setMsg("登陆失败");
				System.out.println("登陆失败");
			}
		}else {
			result.setCode(ResultUtils.CODE_EXCEPTION);
			result.setMsg("用户不匹配");
			System.out.println("用户不匹配");
		}
		System.out.println("--------------------执行回调开始----------------------");
		return result;
	}
	
	
	/***
	 * 二维码生成
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/getCodeImage", method =RequestMethod.GET)
	public void getCodeImage(HttpServletRequest request,HttpServletResponse response,@RequestParam("token")String token){
		System.out.println("--------------------生成二维码开始----------------------");
		System.out.println("token:"+token);
		userToken=token;//记录用户token
		//且给token生成对应的二维码
		
		//获取biztoken
		 try{
			//回调地址
            String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
			String backUrl=basePath+"weixin/auth";
			//拼接地址
			String url = "https://open.weixin.qq.com/connect/oauth2/authorize"
			+"?appid="+wx_appid
			+"&redirect_uri="+backUrl
			+"&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
			logger.info("完整地址："+url);
			//生成二维码
			 ServletOutputStream stream = response.getOutputStream();
				String format = "png";
				// 二维码参数
				Map hints = new HashMap<>();
				hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
				hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
				hints.put(EncodeHintType.MARGIN, 0);
				BitMatrix bitMatrix;
				try {
					bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 350, 350,hints);
					bitMatrix = deleteWhite(bitMatrix);
					MatrixToImageWriter.writeToStream(bitMatrix, format, stream);
				} catch (WriterException e) {
					e.printStackTrace();
				}
        } catch (Exception e) {
            e.printStackTrace();
        }
		 System.out.println("--------------------生成二维码结束----------------------");
	}
	
	
	public static BitMatrix deleteWhite(BitMatrix bitMatrix) {
		int[] rec = bitMatrix.getEnclosingRectangle();
		int resWidth  = rec[2] + 1;
		int resHeight = rec[3] + 1;
		BitMatrix resMatrix = new BitMatrix(resWidth,resHeight);
		resMatrix.clear();
		for (int i = 0; i < resWidth; i++) {
			for (int j = 0; j < resHeight; j++) {
				if(bitMatrix.get(i+rec[0], j+rec[1])){
					resMatrix.set(i, j);
				}
			}
		}
		return resMatrix;
	}
	
	
	
}
